+2000-12-08 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
+ that cause a segfault on text insertion
+
+ * gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
+ warning
+
+ * gtk/gtktextiter.c (test_log_attrs): use
+ _gtk_text_buffer_get_line_log_attrs to speed things up a bit
+
+ * gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
+ Get log attrs for a line, using a cache stored on the buffer
+
+ * gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
+ reported by Jeff Franks
+
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
+
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
+2000-12-08 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
+ that cause a segfault on text insertion
+
+ * gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
+ warning
+
+ * gtk/gtktextiter.c (test_log_attrs): use
+ _gtk_text_buffer_get_line_log_attrs to speed things up a bit
+
+ * gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
+ Get log attrs for a line, using a cache stored on the buffer
+
+ * gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
+ reported by Jeff Franks
+
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
+
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
+2000-12-08 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
+ that cause a segfault on text insertion
+
+ * gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
+ warning
+
+ * gtk/gtktextiter.c (test_log_attrs): use
+ _gtk_text_buffer_get_line_log_attrs to speed things up a bit
+
+ * gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
+ Get log attrs for a line, using a cache stored on the buffer
+
+ * gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
+ reported by Jeff Franks
+
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
+
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
+2000-12-08 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
+ that cause a segfault on text insertion
+
+ * gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
+ warning
+
+ * gtk/gtktextiter.c (test_log_attrs): use
+ _gtk_text_buffer_get_line_log_attrs to speed things up a bit
+
+ * gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
+ Get log attrs for a line, using a cache stored on the buffer
+
+ * gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
+ reported by Jeff Franks
+
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
+
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
+2000-12-08 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
+ that cause a segfault on text insertion
+
+ * gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
+ warning
+
+ * gtk/gtktextiter.c (test_log_attrs): use
+ _gtk_text_buffer_get_line_log_attrs to speed things up a bit
+
+ * gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
+ Get log attrs for a line, using a cache stored on the buffer
+
+ * gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
+ reported by Jeff Franks
+
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
+
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
+2000-12-08 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
+ that cause a segfault on text insertion
+
+ * gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
+ warning
+
+ * gtk/gtktextiter.c (test_log_attrs): use
+ _gtk_text_buffer_get_line_log_attrs to speed things up a bit
+
+ * gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
+ Get log attrs for a line, using a cache stored on the buffer
+
+ * gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
+ reported by Jeff Franks
+
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
+
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
+2000-12-08 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
+ that cause a segfault on text insertion
+
+ * gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
+ warning
+
+ * gtk/gtktextiter.c (test_log_attrs): use
+ _gtk_text_buffer_get_line_log_attrs to speed things up a bit
+
+ * gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
+ Get log attrs for a line, using a cache stored on the buffer
+
+ * gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
+ reported by Jeff Franks
+
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
+
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
#define GTK_COLOR_SELECTION_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_COLOR_SELECTION, GtkColorSelectionClass))
#define GTK_IS_COLOR_SELECTION(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_COLOR_SELECTION))
#define GTK_IS_COLOR_SELECTION_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), GTK_TYPE_COLOR_SELECTION))
-#define GTK_COLOR_SELECTION_GET_CLASS(obj) (GTK_CHECK_GET_CLAS ((obj), GTK_TYPE_COLOR_SELECTION, GtkColorSelectionClass))
+#define GTK_COLOR_SELECTION_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_COLOR_SELECTION, GtkColorSelectionClass))
typedef struct _GtkColorSelection GtkColorSelection;
&delim,
&eol);
+ /* make these relative to the start of the text */
+ delim += sol;
+ eol += sol;
+
chunk_len = eol - sol;
seg = _gtk_char_segment_new (&text[sol], chunk_len);
static void gtk_text_buffer_real_changed (GtkTextBuffer *buffer);
static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
+static void free_log_attr_cache (GtkTextLogAttrCache *cache);
static GtkObjectClass *parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 };
gtk_text_btree_unref (buffer->btree);
buffer->btree = NULL;
}
+
+ if (buffer->log_attr_cache)
+ free_log_attr_cache (buffer->log_attr_cache);
+
+ buffer->log_attr_cache = NULL;
G_OBJECT_CLASS (parent_class)->finalize (object);
}
return gtk_text_btree_get_selection_bounds (get_btree (buffer), start, end);
}
+/*
+ * Logical attribute cache
+ */
+
+#define ATTR_CACHE_SIZE 2
+
+typedef struct _CacheEntry CacheEntry;
+struct _CacheEntry
+{
+ gint line;
+ gint char_len;
+ PangoLogAttr *attrs;
+};
+
+
+struct _GtkTextLogAttrCache
+{
+ gint chars_changed_stamp;
+ CacheEntry entries[ATTR_CACHE_SIZE];
+};
+
+static void
+free_log_attr_cache (GtkTextLogAttrCache *cache)
+{
+ gint i = 0;
+ while (i < ATTR_CACHE_SIZE)
+ {
+ g_free (cache->entries[i].attrs);
+ ++i;
+ }
+ g_free (cache);
+}
+
+static void
+clear_log_attr_cache (GtkTextLogAttrCache *cache)
+{
+ gint i = 0;
+ while (i < ATTR_CACHE_SIZE)
+ {
+ g_free (cache->entries[i].attrs);
+ cache->entries[i].attrs = NULL;
+ ++i;
+ }
+}
+
+static PangoLogAttr*
+compute_log_attrs (const GtkTextIter *iter,
+ gint *char_lenp)
+{
+ GtkTextIter start;
+ GtkTextIter end;
+ gchar *paragraph;
+ gint char_len, byte_len;
+ PangoLogAttr *attrs = NULL;
+ gchar *lang;
+
+ start = *iter;
+ end = *iter;
+
+ gtk_text_iter_set_line_offset (&start, 0);
+ gtk_text_iter_forward_line (&end);
+
+ paragraph = gtk_text_iter_get_slice (&start, &end);
+ char_len = g_utf8_strlen (paragraph, -1);
+ byte_len = strlen (paragraph);
+
+ g_assert (char_len > 0);
+
+ if (char_lenp)
+ *char_lenp = char_len;
+
+ attrs = g_new (PangoLogAttr, char_len);
+
+ lang = gtk_text_iter_get_language (&start);
+
+ pango_get_log_attrs (paragraph, byte_len, -1,
+ lang,
+ attrs);
+
+ g_free (lang);
+
+ g_free (paragraph);
+
+ return attrs;
+}
+
+/* The return value from this is valid until you call this a second time.
+ */
+const PangoLogAttr*
+_gtk_text_buffer_get_line_log_attrs (GtkTextBuffer *buffer,
+ const GtkTextIter *anywhere_in_line,
+ gint *char_len)
+{
+ gint line;
+ GtkTextLogAttrCache *cache;
+ gint i;
+
+ g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
+ g_return_val_if_fail (anywhere_in_line != NULL, NULL);
+ g_return_val_if_fail (!gtk_text_iter_is_last (anywhere_in_line), NULL);
+
+ /* FIXME we also need to recompute log attrs if the language tag at
+ * the start of a paragraph changes
+ */
+
+ if (buffer->log_attr_cache == NULL)
+ {
+ buffer->log_attr_cache = g_new0 (GtkTextLogAttrCache, 1);
+ buffer->log_attr_cache->chars_changed_stamp =
+ gtk_text_btree_get_chars_changed_stamp (get_btree (buffer));
+ }
+ else if (buffer->log_attr_cache->chars_changed_stamp !=
+ gtk_text_btree_get_chars_changed_stamp (get_btree (buffer)))
+ {
+ clear_log_attr_cache (buffer->log_attr_cache);
+ }
+
+ cache = buffer->log_attr_cache;
+ line = gtk_text_iter_get_line (anywhere_in_line);
+
+ i = 0;
+ while (i < ATTR_CACHE_SIZE)
+ {
+ if (cache->entries[i].attrs &&
+ cache->entries[i].line == line)
+ {
+ if (char_len)
+ *char_len = cache->entries[i].char_len;
+ return cache->entries[i].attrs;
+ }
+ ++i;
+ }
+
+ /* Not in cache; open up the first cache entry */
+ if (cache->entries[ATTR_CACHE_SIZE-1].attrs)
+ g_free (cache->entries[ATTR_CACHE_SIZE-1].attrs);
+
+ g_memmove (cache->entries + 1, cache->entries,
+ sizeof (CacheEntry) * (ATTR_CACHE_SIZE - 1));
+
+ cache->entries[0].line = line;
+ cache->entries[0].attrs = compute_log_attrs (anywhere_in_line,
+ &cache->entries[0].char_len);
+
+ if (char_len)
+ *char_len = cache->entries[0].char_len;
+
+ return cache->entries[0].attrs;
+}
/*
* Debug spew
typedef struct _GtkTextBTree GtkTextBTree;
+typedef struct _GtkTextLogAttrCache GtkTextLogAttrCache;
+
#define GTK_TYPE_TEXT_BUFFER (gtk_text_buffer_get_type ())
#define GTK_TEXT_BUFFER(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_TEXT_BUFFER, GtkTextBuffer))
#define GTK_TEXT_BUFFER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TEXT_BUFFER, GtkTextBufferClass))
GtkTextBTree *btree;
GtkTextBuffer *clipboard_contents;
+
+ GtkTextLogAttrCache *log_attr_cache;
/* Whether the buffer has been modified since last save */
guint modified : 1;
GtkTextIter *end);
gboolean gtk_text_buffer_delete_selection (GtkTextBuffer *buffer,
gboolean interactive,
- gboolean default_editable);
-
+ gboolean default_editable);
+
/* INTERNAL private stuff */
void _gtk_text_buffer_spew (GtkTextBuffer *buffer);
GtkTextBTree* _gtk_text_buffer_get_btree (GtkTextBuffer *buffer);
+const PangoLogAttr* _gtk_text_buffer_get_line_log_attrs (GtkTextBuffer *buffer,
+ const GtkTextIter *anywhere_in_line,
+ gint *char_len);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
seg = anchor->segment;
if (seg->body.child.tree == NULL)
- return NULL;
+ return;
gtk_text_buffer_get_iter_at_child_anchor (layout->buffer,
&start, anchor);
*
* Return value: language in effect at @iter
**/
-static gchar*
+gchar*
gtk_text_iter_get_language (const GtkTextIter *iter)
{
GtkTextAttributes *values;
}
}
-typedef gboolean (* FindLogAttrFunc) (PangoLogAttr *attrs,
- gint offset,
- gint min_offset,
- gint len,
- gint *found_offset);
+typedef gboolean (* FindLogAttrFunc) (const PangoLogAttr *attrs,
+ gint offset,
+ gint min_offset,
+ gint len,
+ gint *found_offset);
static gboolean
-find_word_end_func (PangoLogAttr *attrs,
+find_word_end_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
}
static gboolean
-is_word_end_func (PangoLogAttr *attrs,
+is_word_end_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
}
static gboolean
-find_word_start_func (PangoLogAttr *attrs,
+find_word_start_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
}
static gboolean
-is_word_start_func (PangoLogAttr *attrs,
+is_word_start_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
}
static gboolean
-inside_word_func (PangoLogAttr *attrs,
+inside_word_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
}
static gboolean
-test_log_attrs (GtkTextIter *iter,
+test_log_attrs (const GtkTextIter *iter,
FindLogAttrFunc func,
gint *found_offset)
{
- GtkTextIter start;
- GtkTextIter end;
gchar *paragraph;
- gint char_len, byte_len;
- PangoLogAttr *attrs;
+ gint char_len;
+ const PangoLogAttr *attrs;
int offset;
gboolean result = FALSE;
g_return_val_if_fail (iter != NULL, FALSE);
- start = *iter;
- end = *iter;
-
- gtk_text_iter_set_line_offset (&start, 0);
- gtk_text_iter_forward_line (&end);
-
- paragraph = gtk_text_iter_get_slice (&start, &end);
- char_len = g_utf8_strlen (paragraph, -1);
- byte_len = strlen (paragraph);
+ attrs = _gtk_text_buffer_get_line_log_attrs (gtk_text_iter_get_buffer (iter),
+ iter, &char_len);
offset = gtk_text_iter_get_line_offset (iter);
- if (char_len > 0 && offset < char_len)
- {
- gchar *lang;
-
- attrs = g_new (PangoLogAttr, char_len);
-
- lang = gtk_text_iter_get_language (iter);
-
- pango_get_log_attrs (paragraph, byte_len, -1,
- lang,
- attrs);
-
- g_free (lang);
-
- result = (* func) (attrs, offset, 0, char_len, found_offset);
-
- g_free (attrs);
- }
-
- g_free (paragraph);
+ g_assert (char_len > 0);
+
+ if (offset < char_len)
+ result = (* func) (attrs, offset, 0, char_len, found_offset);
return result;
}
gint gtk_text_iter_get_chars_in_line (const GtkTextIter *iter);
gboolean gtk_text_iter_get_attributes (const GtkTextIter *iter,
- GtkTextAttributes *values);
-
+ GtkTextAttributes *values);
+gchar* gtk_text_iter_get_language (const GtkTextIter *iter);
gboolean gtk_text_iter_is_last (const GtkTextIter *iter);
gboolean gtk_text_iter_is_first (const GtkTextIter *iter);